package com.smedi.ismedi.authority.starter.util;

import com.smedi.ismedi.authority.starter.constant.WebParameterConstant;
import com.smedi.ismedi.authority.starter.exception.BasicError;
import com.smedi.ismedi.authority.starter.exception.LogicException;
import com.smedi.ismedi.authority.starter.feign.AuthorityAccessFeignClient;
import com.smedi.ismedi.authority.starter.response.AuthorityAccessResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

import static com.smedi.ismedi.authority.starter.constant.AuthorityConstant.ISMEDI_ACCESS_TOKEN;
import static com.smedi.ismedi.authority.starter.context.CurrentUserHelper.infoContext;
import static com.smedi.ismedi.authority.starter.context.CurrentUserHelper.tokenContext;

/**
 * @Author: xulinjun
 * @Date: 2021-6-29 17:56
 */
@Slf4j
@Component
@AllArgsConstructor
public class AuthorityUtil {

    private final JsonHelper jsonHelper;
    private final AuthorityAccessFeignClient authorityAccessFeignClient;

    /**
     * 获取人员信息
     *
     * @return
     */
    public AuthorityAccessResponse getLoginAccess() {
        String info = infoContext.get();
        if (VerifyHelper.isAvailable(info)) {
            return jsonHelper.jsonToObject(info, AuthorityAccessResponse.class);
        }

        String token = tokenContext.get();
        if (!VerifyHelper.isAvailable(token)) {
            log.error("该接口需要用户信息，但未传入票据令牌！请传入票据令牌后重试！");
            throw LogicException.raise(BasicError.NEED_INFO_BUT_TOKEN_MISS);
        }

        AuthorityAccessResponse accessInfo = authorityAccessFeignClient.getCurrentUserInfo().getData();
        if (null != accessInfo) {
            infoContext.set(jsonHelper.objectToJson(accessInfo));
        }
        return accessInfo;
    }

    /**
     * 获取当前人员id
     *
     * @return
     */
    public Long getPersonId() {
        return this.getLoginAccess().getPersonId();
    }

    /**
     * 是否是企业人员
     *
     * @return
     */
    public Boolean isInternal() {
        return this.getLoginAccess().isInternal();
    }

    /**
     * 获取当前人员是否为管理员
     *
     * @return
     */
    public Boolean isAdmin() {
        return this.getLoginAccess().isAdmin();
    }

    /**
     * 0 获取头参数，
     * 1 获取地址参数
     * 2 获取 Request Session 参数
     * 3 获取 Context 参数
     *
     * @return
     */
    public String getAccessToken() {
        return tokenContext.get();
//        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        String token = request.getHeader(ISMEDI_ACCESS_TOKEN);
//
//        if (StringUtils.isEmpty(token)) {
//            // 如果token抓取不到，则在参数中抓取
//            token = request.getParameter(ISMEDI_ACCESS_TOKEN);
//
//            if (StringUtils.isEmpty(token)) {
//                // 获取Session参数
//                if (request.getSession() != null) {
//                    token = String.valueOf(request.getSession().getAttribute(ISMEDI_ACCESS_TOKEN)); // 同步情况
//                } else {
//                    token = String.valueOf(RequestContextHolder.getRequestAttributes().getAttribute(ISMEDI_ACCESS_TOKEN, WebParameterConstant.requestScope)); // 异步情况
//                }
//            }
//        }
//
//        if (!StringUtils.isEmpty(token)) {
//            return token;
//        } else {
//            throw LogicException.raise(BasicError.TOKEN_MISS);
//        }
    }

    /**
     * 获取不抛错的token
     *
     * @return
     */
    public String getAccessTokenWithNoThrown() {
        try {
            return getAccessToken();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取数据范围
     *
     * @return
     */
    public Map<String, List<Long>> getDataScope() {
        return this.getLoginAccess().getDataScope();
    }
}
